<?php
/**
 * spCache
 * 函数和数据缓存实现
 */
class spCache {
	private $dir;
	/**
	 * 默认的数据生存期
	 */
	public $life_time = 3600;
	
	/**
	 * 模型对象
	 */
	private $model_obj = null;
	
	/** 
	 * 调用时输入的参数
	 */
	public $time = null;

	public function __construct($dir,$time){
		$this->dir=$dir;
		$this->time = $time;
	}
	public function set_model_obj($obj){
		$this->model_obj = $obj;
	}

	public function get($func_name, $func_args){
		$cache_id = get_class($this->model_obj) . md5($func_name);
		if( null != $func_args )$cache_id .= md5(json_encode($func_args));
		if( $cache_file = sys_file_cache($this->dir,'r', "sp_cache_{$cache_id}") ){
			return array(true,unserialize( $cache_file ));
		}else{
			return array(false,array());
		}
	}
	public function set($func_name, $func_args, $d){
		$cache_id = get_class($this->model_obj) . md5($func_name);
		if( null != $func_args )$cache_id .= md5(json_encode($func_args));
		return $this->cache_obj($cache_id, $d, $this->time);
	}
	/** 
	 * 执行spModel子类对象的方法，并对返回结果进行缓存。
	 *
	 * @param obj    引用的spModel子类对象
	 * @param func_name    需要执行的函数名称
	 * @param func_args    函数的参数
	 * @param life_time    缓存生存时间
	 */
	public function cache_obj($cache_id, $run_result, $life_time = null ){
		if( null == $life_time )$life_time = $this->life_time;
		sys_file_cache($this->dir,'w', "sp_cache_{$cache_id}", serialize($run_result), $life_time);
		if( $cache_list = sys_file_cache($this->dir,'r', 'sp_cache_list') ){
			$cache_list = explode("\n",$cache_list);
			if( ! in_array( $cache_id, $cache_list ) )sys_file_cache($this->dir,'w', 'sp_cache_list', join("\n", $cache_list) . $cache_id . "\n");
		}else{
			sys_file_cache($this->dir,'w', 'sp_cache_list', $cache_id . "\n");
		}
		return $run_result;
	}
	/** 
	 * 清除单个函数缓存的数据
	 *
	 * @param obj    引用的spModel子类对象
	 * @param func_name    需要执行的函数名称
	 * @param func_args    函数的参数，在默认不输入参数的情况下，将清除全部该函数生成的缓存。
	 * 如果func_args有设置，将只会清除该参数产生的缓存。
	 */
	public function clear(& $obj, $func_name, $func_args = null){
		$cache_id = get_class($obj) . md5($func_name);
		if( null != $func_args )$cache_id .= md5(json_encode($func_args));
		if( $cache_list = sys_file_cache($this->dir,'r', 'sp_cache_list') ){
			$cache_list = explode("\n",$cache_list);
			$cache_list=array_filter($cache_list);
			$new_list = '';
			foreach( $cache_list as $single_item ){
				if( $single_item == $cache_id || ( null == $func_args && substr($single_item,0,strlen($cache_id)) == $cache_id ) ){
					sys_file_cache($this->dir,'c', "sp_cache_{$single_item}");
				}else{
					$new_list .= $single_item. "\n";
				}
			}
			sys_file_cache($this->dir,'w', 'sp_cache_list', substr($new_list,0,-1));
		}
		return TRUE;
	}
	/** 
	 * 清除全部函数缓存的数据
	 *
	 */
	public function clear_all(){
		if( $cache_list = sys_file_cache($this->dir,'r', 'sp_cache_list') ){
			$cache_list = explode("\n",$cache_list);
			$cache_list=array_filter($cache_list);
			foreach( $cache_list as $single_item )sys_file_cache($this->dir,'c', "sp_cache_{$single_item}");
			sys_file_cache($this->dir,'c', 'sp_cache_list');
		}
		return TRUE;
	}
}
